package tech.yixiyun.framework.kuafu.controller.route;

import tech.yixiyun.framework.kuafu.config.AppConfig;
import tech.yixiyun.framework.kuafu.config.ConfigKey;
import tech.yixiyun.framework.kuafu.controller.annotation.Upload;
import tech.yixiyun.framework.kuafu.controller.request.param.ParamDefinition;
import tech.yixiyun.framework.kuafu.kits.StringKit;
import tech.yixiyun.framework.kuafu.kits.TaskKit;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;


public class RouteNode {

    /**
     * 根访问路径
     */
    public static final String ROOT_PATH = "/";

    /**
     * 节点的path
     */
    private String path;

    /**
     * 节点对应的方法
     */
    private Method method;

    /**
     * 解析出来的方法参数
     */
    private ParamDefinition[] params;

    /**
     * 针对上传请求的文件保存路径
     */
    private String savePath;

    /**
     * 针对上传请求的单次最大大小
     */
    private long totalMaxSize;

    /**
     * 针对上传请求的单文件最大大小
     */
    private long singleMaxSize;


    public RouteNode(String path , Method method) {
        this.path = path;
        this.method = method;
        TaskKit.execute(() -> {
            this.params = resolveParams(method.getParameters());
        });

    }

    /**
     * 重新解析params，这个方法只在热加载插件中调用，请开发者在生产环境不要调用此方法。
     */
    public void reloadParams() {
        this.params = null;
    }

    private void resolveUpload() {
        Upload upload = method.getDeclaredAnnotation(Upload.class);
        if (upload != null) {
            this.savePath = upload.savePath();
            this.totalMaxSize = upload.totalMaxSize();
            this.singleMaxSize = upload.singleMaxSize();
        }
        if (StringKit.isBlank(this.savePath)) {
            this.savePath = AppConfig.getAsString(ConfigKey.UPLOAD_SAVEPATH, "/upload/{date:yyyyMMdd}/{uuid}.{suffix}");
        }
        if (totalMaxSize <= 0) {
            this.totalMaxSize = AppConfig.getAsLong(ConfigKey.UPLOAD_TOTALMAXSIZE, 10240);
        }
        if (singleMaxSize <= 0) {
            this.singleMaxSize = AppConfig.getAsLong(ConfigKey.UPLOAD_SINGLEMAXSIZE, 10240);
        }
    }

    /**
     * 解析方法参数
     * @param params
     * @return
     */
    private ParamDefinition[] resolveParams(Parameter[] params) {
        ParamDefinition[] definitions = new ParamDefinition[params.length];
        for (int i = 0; i < params.length; i++) {
            Parameter param = params[i];
            definitions[i] = new ParamDefinition(param);
        }
        return definitions;
    }


    public String getPath() {
        return path;
    }



    public Method getMethod() {
        return method;
    }

    public void setMethod(Method method) {
        this.method = method;
    }

    public ParamDefinition[] getParams() {
        if (params == null) {
            this.params = resolveParams(method.getParameters());
        }
        return params;
    }

    public String getSavePath() {
        if (savePath == null) {
            resolveUpload();
        }
        return savePath;
    }

    public long getTotalMaxSize() {
        if (savePath == null) {
            resolveUpload();
        }
        return totalMaxSize;
    }

    public long getSingleMaxSize() {
        if (savePath == null) {
            resolveUpload();
        }
        return singleMaxSize;
    }
}
